﻿namespace MongoDBController
{
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using MongoDB.Bson;
    using MongoDB.Driver;
    using MongoDB.Driver.Linq;
    using SQLServer.Data.EntityFramework;
    using SQLServer.Models.EntityFramework;

    public class MongoDBProvider
    {
        private MongoCollection productReports = MongoDBProvider.DB.GetCollection("Product reports");

        private MongoCollection productExpences = MongoDBProvider.DB.GetCollection("Expenses");

        public static MongoDatabase DB
        {
            get
            {
                // var connectionString = "mongodb://Admin:parola1@ds037358.mongolab.com:37358/product_reports_db";
                var connectionString = "mongodb://localhost/";
                var mongoClient = new MongoClient(connectionString);
                var mongoServer = mongoClient.GetServer();
                var clicksDb = mongoServer.GetDatabase("product_reports_db");

                var databaseName = "product_reports_db";
                var databaseConnection = mongoServer.GetDatabase(databaseName);

                return databaseConnection;
            }
        }

        public IQueryable<ProductReportJson> ListAllReports()
        {
            return MongoDBProvider.DB.GetCollection<ProductReportJson>("Product reports").AsQueryable();
        }

        public IQueryable<Expense> ListAllExpenses()
        {
            return MongoDBProvider.DB.GetCollection<Expense>("Expenses").AsQueryable();
        }

        public void InsertProductReports()
        {
            var collection = this.GenerateProductReports();

            foreach (ProductReportJson report in collection)
            {
                this.productReports.Insert<ProductReportJson>(report);
            }

            MongoDBProvider.DB.Server.Connect();
        }

        public void InsertExpence(Expense expence)
        {
            this.productExpences.Insert<Expense>(expence);
        }

        private ICollection<ProductReportJson> GenerateProductReports()
        {
            var collection = new List<ProductReportJson>();
            using (SupermarketEntitiesSQLServer marketContext = new SupermarketEntitiesSQLServer())
            {
                var productReports = from sale in marketContext.Sales
                                     join prod in marketContext.Products on sale.ProductID equals prod.ID
                                     join v in marketContext.Vendors on prod.VendorId equals v.ID
                                     // join d in marketContext.Dates on sale.ID equals d.ID
                                     select new ProductReportJson
                                     {
                                         ProductId = prod.ID,
                                         ProductName = prod.ProductName,
                                         VendorName = v.Name,
                                         TotalQuantitySold = sale.Quantity,
                                         TotalIncomes = sale.Sum
                                     };

                foreach (ProductReportJson productReport in productReports)
                {
                    collection.Add(productReport);
                }
            }

            return collection;
        }

        public void SaveProductReportToHDD()
        {
            var reports = this.productReports.FindAllAs<ProductReportJson>();

            foreach (ProductReportJson item in reports)
            {
                var reportAsJsonString = item.ToJson();
                var productId = item.ProductId;
                string path = @"../../Product-Reports/" + productId + ".json";
                StreamWriter writer = new StreamWriter(path);

                using (writer)
                {
                    writer.Write(reportAsJsonString);
                }
            }
        }

        public void DropAllCollections()
        {
            MongoDBProvider.DB.GetCollection("Product reports").Drop();
            MongoDBProvider.DB.GetCollection("Expenses").Drop();
        }
    }
}
